/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * TransformingNodeInspectorPanel.java
 *
 * Created on 2011/2/12, 下午 09:53:03
 */

package elaborate.h2x.tester;

import elaborate.h2x.transform.TransformingModel;
import elaborate.h2x.transform.TransformingNode;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.util.Arrays;
import java.util.Collection;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JTable;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreeNode;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

/**
 *
 * @author lendle
 */
public class TransformingNodeInspectorPanel extends javax.swing.JPanel {
    private TransformingModel transformingModel=null;
    /** Creates new form TransformingNodeInspectorPanel */
    public TransformingNodeInspectorPanel() {
        initComponents();
        this.transformingNodeTree.setRootVisible(false);
        DefaultMutableTreeNode root=new DefaultMutableTreeNode();
        ((DefaultTreeModel)this.transformingNodeTree.getModel()).setRoot(root);
    }

    public JTable getTransformingNodeDetail() {
        return transformingNodeDetail;
    }

    public JTree getTransformingNodeTree() {
        return transformingNodeTree;
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jScrollPane1 = new javax.swing.JScrollPane();
        jSplitPane1 = new javax.swing.JSplitPane();
        jScrollPane2 = new javax.swing.JScrollPane();
        transformingNodeTree = new javax.swing.JTree();
        jScrollPane3 = new javax.swing.JScrollPane();
        transformingNodeDetail = new javax.swing.JTable();

        setLayout(new java.awt.BorderLayout());

        jSplitPane1.setDividerLocation(200);

        transformingNodeTree.addTreeSelectionListener(new javax.swing.event.TreeSelectionListener() {
            public void valueChanged(javax.swing.event.TreeSelectionEvent evt) {
                transformingNodeTreeValueChanged(evt);
            }
        });
        jScrollPane2.setViewportView(transformingNodeTree);

        jSplitPane1.setLeftComponent(jScrollPane2);

        transformingNodeDetail.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {
                "Property", "Value"
            }
        ));
        jScrollPane3.setViewportView(transformingNodeDetail);

        jSplitPane1.setRightComponent(jScrollPane3);

        jScrollPane1.setViewportView(jSplitPane1);

        add(jScrollPane1, java.awt.BorderLayout.CENTER);
    }// </editor-fold>//GEN-END:initComponents

    private void transformingNodeTreeValueChanged(javax.swing.event.TreeSelectionEvent evt) {//GEN-FIRST:event_transformingNodeTreeValueChanged
        // TODO add your handling code here:
        while(((DefaultTableModel)this.transformingNodeDetail.getModel()).getRowCount()>0){
            ((DefaultTableModel)this.transformingNodeDetail.getModel()).removeRow(0);
        }
        
        DefaultMutableTreeNode node=(DefaultMutableTreeNode) evt.getPath().getLastPathComponent();
        TransformingNode transformingNode=(TransformingNode) node.getUserObject();
        try {
            BeanInfo info = Introspector.getBeanInfo(transformingNode.getClass());
            PropertyDescriptor [] pds=info.getPropertyDescriptors();
            if(pds!=null){
                for(PropertyDescriptor pd : pds){
                    String propName=pd.getDisplayName();
                    Object value=pd.getReadMethod().invoke(transformingNode);
                    String stringValue=(value instanceof Collection)?
                        (Arrays.deepToString(((Collection)value).toArray())):""+value;
                    ((DefaultTableModel)this.transformingNodeDetail.getModel()).addRow(new Object[]{propName, stringValue});
                }
            }
        } catch (Exception ex) {
            Logger.getLogger(TransformingNodeInspectorPanel.class.getName()).log(Level.SEVERE, null, ex);
        }
    }//GEN-LAST:event_transformingNodeTreeValueChanged

    public void setTransformingModel(TransformingModel transformingModel){
        this.transformingModel = transformingModel;
        DefaultMutableTreeNode root = (DefaultMutableTreeNode) ((DefaultTreeModel) this.transformingNodeTree.getModel()).getRoot();
        if (root.getChildCount() > 0) {
            root.removeAllChildren();
        }
        Document doc = this.transformingModel.getDocument();
        Element rootElement = doc.getDocumentElement();
        root.add((MutableTreeNode) this.createSubTree(rootElement));
        for (int i = 0; i < transformingNodeTree.getRowCount(); i++) {
            transformingNodeTree.expandRow(i);
        }
        while(((DefaultTableModel)this.transformingNodeDetail.getModel()).getRowCount()>0){
            ((DefaultTableModel)this.transformingNodeDetail.getModel()).removeRow(0);
        }

        SwingUtilities.invokeLater(new Runnable() {

            public void run() {
                transformingNodeTree.updateUI();
                transformingNodeDetail.updateUI();
            }
        });
        
    }

    private TreeNode createSubTree(Node node){
        DefaultMutableTreeNode treeNode=new DefaultMutableTreeNode();
        treeNode.setUserObject(this.transformingModel.getNode(node));
        Node childNode=node.getFirstChild();
        while(childNode!=null){
            DefaultMutableTreeNode childTreeNode=(DefaultMutableTreeNode) this.createSubTree(childNode);
            treeNode.add(childTreeNode);
            childNode=childNode.getNextSibling();
        }
        return treeNode;
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JScrollPane jScrollPane3;
    private javax.swing.JSplitPane jSplitPane1;
    private javax.swing.JTable transformingNodeDetail;
    private javax.swing.JTree transformingNodeTree;
    // End of variables declaration//GEN-END:variables

}
